/**
 * Created by cchen on 2015/5/19.
 */
Date.prototype.format = function (format) {
    var o = {
        "M+": this.getMonth() + 1, //month
        "d+": this.getDate(), //day
        "h+": this.getHours(), //hour
        "m+": this.getMinutes(), //minute
        "s+": this.getSeconds(), //second
        "q+": Math.floor((this.getMonth() + 3) / 3), //quarter
        "S": this.getMilliseconds() //millisecond
    }
    if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
        (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o) if (new RegExp("(" + k + ")").test(format))
        format = format.replace(RegExp.$1,
            RegExp.$1.length == 1 ? o[k] :
                ("00" + o[k]).substr(("" + o[k]).length));
    return format;
}

String.prototype.format = function () {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function (match, number) {
        return typeof args[number] != 'undefined'
            ? args[number]
            : match;
    });
};
String.prototype.capitalize = function () {
    return this.charAt(0).toUpperCase() + this.slice(1)
}
String.prototype.replaceAll = function (oldStr, newStr) {
    return this.replace(new RegExp(oldStr, 'g'), newStr);
}

function getYesterdaysDate() {
    var date = new Date();
    date.setDate(date.getDate() - 1);
    return date.format('yyyy-MM-dd')
}

function newIncrementDate(startDate, dayIncrement) {
    var tempDate = new Date(startDate)
    var newDate = new Date(tempDate.setDate(tempDate.getDate() + dayIncrement));
    return newDate
}

function convertDictToList(dict) {
    var list = []
    for (i in dict)
        list.push(i)
    return list;
}

function generateDaysList(startDate, endDate) {
    var start = new Date(startDate)
    var end = new Date(endDate);
    var msDay = 60 * 60 * 24 * 1000
    var list = []

    var day_difference = Math.floor((end - start) / msDay)

    for (var i = 0; i <= day_difference; i++) {
        var tempdate = new Date(start)
        var newday = new Date(tempdate.setDate(tempdate.getDate() + i));
        list.push(newday.format("yyyy-MM-dd"))
    }
    return list
}
function generateWeeksList(startDate, endDate) {
    var start = new Date(startDate)
    var end = new Date(endDate);
    var msDay = 60 * 60 * 24 * 1000
    var list = []

    var day_difference = Math.floor((end - start) / msDay)

    for (var i = 0; i <= day_difference; i++) {
        if (i % 7 == 0) {
            var tempdate = new Date(start)
            var newweek = new Date(tempdate.setDate(tempdate.getDate() + i));
            list.push(newweek.format("yyyy-MM-dd"))
        }
    }
    return list
}
function generateMonthsList(startDate, endDate) {

    var start = new Date(startDate)
    var end = new Date(endDate)

    var monthsList = []

    var x = 0
    while (true) {
        var tempdate = new Date(start)
        var newMonth = new Date(tempdate.setMonth(tempdate.getMonth() + x))
        if (newMonth > end)
            break
        monthsList.push(newMonth.format('yyyy-MM-dd'))
        x++
    }
    return monthsList
}
function startAndEndOfWeek(date) {

    var d = date ? new Date(date) : new Date();

    if (d.getDay() == 0)
        d.setDate(d.getDate() - 1)
    d.setHours(0, 0, 0, 0);

    // Get the previous Monday
    var monday = new Date(d);
    monday.setDate(monday.getDate() - monday.getDay() + 1);

    // Get next Sunday
    var sunday = new Date(d);
    sunday.setDate(sunday.getDate() - sunday.getDay() + 7);

    return [monday.format('yyyy-MM-dd'), sunday.format('yyyy-MM-dd')];
}

function startAndEndOfMonth(date) {

    var now = date ? new Date(date).format('yyyy-MM-dd') : new Date().format('yyyy-MM-dd');
    var year = now.split('-')[0]
    var month = now.split('-')[1]

    var startMonth = year + '-' + month + '-01'

    var end = new Date(date);
    var endMonth = new Date(end.getFullYear(), end.getMonth() + 1, 0, 23, 59, 59)

    return [startMonth, endMonth.format('yyyy-MM-dd')]
}

function getDayDiff(startDate, endDate) {
    var start = new Date(startDate)
    var end = new Date(endDate);
    var msDay = 60 * 60 * 24 * 1000
    var daydiff = Math.abs(Math.floor((end - start) / msDay))
    return start < end ? daydiff : -daydiff
}

function getWeekDiff(startDate, endDate) {
    return Math.floor(getDayDiff(startDate, endDate) / 7)
}

function getMonthDiff(startDate, endDate) {
    startDate = new Date(startDate)
    endDate = new Date(endDate)
    return endDate.getMonth() -
        startDate.getMonth() +
        (12 * (endDate.getFullYear() - startDate.getFullYear()));
}

function sortOnKeys(dict) {
    var sorted = [];
    for (var key in dict) {
        sorted[sorted.length] = key;
    }
    sorted.sort();

    var tempDict = {};
    for (var i = 0; i < sorted.length; i++) {
        tempDict[sorted[i]] = dict[sorted[i]];
    }

    return tempDict;
}


var onlineDate = '2015-03-08'

/** GRAPH and GRAPH FUNCTIONS */

var dataGraph = {}  // Graph global variable    e.g. dataGraph = {users: {data: {chart:{renderTo:'usersChart'}, ...}}, {question: {data: {chart:{renderTo:'questionChart'},...}} ,...}

function createStandardGraphTemplate(typeOfGraph) {
    var standardGraphTemplate = {
        chart: {
            renderTo: '',
            type: typeOfGraph, // column, spline, ...
            zoomType: 'xy'
        },
        title: {
            text: ''
        },
        subtitle: {
            text: ''
        },
        xAxis: {
            categories: []
        },
        yAxis: {
            min: 0,
            title: {
                text: ''
            },
            labels: {
                format: '',
                style: {}
            },
            stackLabels: {
                enabled: true,
                style: {
                    fontWeight: 'bold',
                    color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
                }
            }
        },
        legend: {
            align: 'right',
            x: -30,
            verticalAlign: 'top',
            y: 25,
            floating: true,
            backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
            borderColor: '#CCC',
            borderWidth: 1,
            shadow: false
        },
        tooltip: {
            formatter: function () {
                return '<b>' + this.x + '</b><br/>' +
                    this.series.name + ': ' + this.y + '<br/>'
                // + 'Total: ' + this.point.stackTotal;
            }
        },
        plotOptions: {
            column: {
                stacking: 'normal',
                dataLabels: {
                    enabled: true,
                    color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
                    style: {
                        textShadow: '0 0 3px black'
                    }
                }
            }
        },
        series: []
    }
    return standardGraphTemplate
}

function createComboGraphTemplate(typeOfPrimaryGraph, typeOfSecondaryGraph) {
    var comboGraphTemplate = {
        chart: {
            renderTo: '',
            zoomType: 'xy'
        },
        title: {
            text: ''
        },
        subtitle: {
            text: ''
        },
        xAxis: [{
            categories: [],
            crosshair: true
        }],
        yAxis: [
            { // Primary yAxis: retentionRate %
                min: 0,
                max: 100,
                title: {
                    text: '',
                    style: {}
                },
                labels: {
                    format: '{value}%',
                    style: {}
                },
                type: typeOfPrimaryGraph       // column, spline, ...
            }, { // Secondary yAxis: 用户数
                title: {
                    text: '',
                    style: {}
                },
                labels: {
                    format: '{value}',
                    style: {}
                },
                opposite: true,
                type: typeOfSecondaryGraph     // column, spline, ...
            }],
        tooltip: {
            shared: false
        },
        legend: {},
        series: []
    }

    return comboGraphTemplate
}

/**  ========= GRAPH FUNCTIONS =========  */
var graphFunctions = {
    setTitle: function (graph, title) {
        dataGraph[graph].data.title.text = title
    },
    setSubtitle: function (graph, subtitle) {
        dataGraph[graph].data.subtitle.text = subtitle
    },
    displayGraph: function (graph) {
        dataGraph[graph].chart = new Highcharts.Chart(dataGraph[graph].data)
    }
}

/**  ========= GRAPH FUNCTIONS FOR STANDARD GRAPHS i.e. graphs with only ONE yAxis) =========  */
graphFunctions.standard = {
    createGraphObject: function (graphName, typeOfGraph, graphTitle, graphSubtitle, yAxisLabels) {
        dataGraph[graphName] = {data: createStandardGraphTemplate(typeOfGraph)}
        dataGraph[graphName].data.chart.renderTo = graphName + 'Chart'
        graphFunctions.setTitle(graphName, graphTitle)
        graphFunctions.setSubtitle(graphName, !graphSubtitle ? '' : graphSubtitle)
        this.yAxis.setTitle(graphName, graphTitle)

        if (yAxisLabels == '%') {
            dataGraph[graphName].data.yAxis.max = 100
            dataGraph[graphName].data.yAxis.labels.format = "{value}%"
        }
    },
    yAxis: {
        setTitle: function (graph, yTitle) {
            dataGraph[graph].data.yAxis.title.text = yTitle
        }
    },
    series: {
        pushDataToGraph: function (graph, seriesName, seriesDataArray) {
            var graphRef = dataGraph[graph].data

            var len = graphRef.series.length
            for (var i = 0; i < len; i++) {
                if (seriesName === graphRef.series[i].name) {
                    if (Object.prototype.toString.call(seriesDataArray) === '[object Array]') {
                        seriesDataArray.forEach(function (item) {
                            graphRef.series[i].data.push(item)
                        })
                    }
                    return
                }
            }
            var newSeries = {name: seriesName, color: this.getGraphSeriesColor(len), data: []}
            if (Object.prototype.toString.call(seriesDataArray) === '[object Array]') {
                seriesDataArray.forEach(function (item) {
                    newSeries.data.push(item)
                })
            }
            graphRef.series.push(newSeries)
        },
        resetSeriesDataInGraph: function (graph, seriesName) {
            dataGraph[graph].data.series.forEach(function (s) {
                if (s.name == seriesName) {
                    s.data = []
                    return
                }
            })
        },
        removeSeriesInGraph: function (graph, seriesName) {
            dataGraph[graph].data.series.forEach(function (s, i) {
                if (s.name == seriesName) {
                    dataGraph[graph].data.series.splice(i, 1)
                    return
                }
            })
        },
        resetAllDataInGraph: function (graph) {
            if (dataGraph[graph].data === 'undefined')
                return false
            dataGraph[graph].data.series.forEach(function (s) {
                s.data = []
            })
        },
        getGraphSeriesColor: function (idx) {
            return Highcharts.getOptions().colors[idx];
        }
    },
    xAxis: {
        clearXAxisCategoryInGraph: function (graph) {
            dataGraph[graph].data.xAxis.categories = []
        }
        ,
        pushXAxisCategoryToGraph: function (graph, category) {
            dataGraph[graph].data.xAxis.categories.push(category)
        }
        ,
        pushTimeCategoryToGraph: function (graph, timeSeries) {
            this.clearXAxisCategoryInGraph(graph)
            var tlen = timeSeries.length
            for (var t = 0; t < tlen; t++)
                this.pushXAxisCategoryToGraph(graph, timeSeries[t])
        }
    }
}
/**  ========= GRAPH FUNCTIONS FOR COMBO GRAPHS i.e. graphs with TWO yAxis) =========  */
graphFunctions.combo = {
    createGraphObject: function (graphName, typeOfPrimaryGraph, typeOfSecondaryGraph, title) {
        dataGraph[graphName] = {data: createComboGraphTemplate(typeOfPrimaryGraph, typeOfSecondaryGraph)}
        dataGraph[graphName].data.chart.renderTo = graphName + 'Chart'
        graphFunctions.setTitle(graphName, title)
    },
    yAxis: {
        primary: {
            setTitle: function (graph, title) {
                dataGraph[graph].data.yAxis[0].title.text = title
            },
            setFormat: function (graph, format) {     // format e.g. {value}, {value}%
                dataGraph[graph].data.yAxis[0].labels.format = format
            }
        },
        secondary: {
            setTitle: function (graph, title) {
                dataGraph[graph].data.yAxis[1].title.text = title
            },
            setFormat: function (graph, format) {     // format e.g. {value}, {value}%
                dataGraph[graph].data.yAxis[1].labels.format = format
            }
        }
    },
    xAxis: {
        clearXAxisCategoryInGraph: function (graph) {
            dataGraph[graph].data.xAxis[0].categories = []
        }
        ,
        pushXAxisCategoryToGraph: function (graph, category) {
            dataGraph[graph].data.xAxis[0].categories.push(category)
        }
        ,
        pushTimeCategoryToGraph: function (graph, timeSeries) {
            this.clearXAxisCategoryInGraph(graph)
            var tlen = timeSeries.length
            for (var t = 0; t < tlen; t++)
                this.pushXAxisCategoryToGraph(graph, timeSeries[t])
        }
    },
    series: {
        pushPrimaryDataToGraph: function (graph, seriesName, seriesPrimaryDataArray) {
            var graphRef = dataGraph[graph].data
            var len = graphRef.series.length
            var idx = Math.floor(len / 2)
            for (var i = 0; i < len; i++) {
                if (seriesName === graphRef.series[i].name && graphRef.yAxis[0].type === graphRef.series[i].type) {
                    if (Object.prototype.toString.call(seriesPrimaryDataArray) === '[object Array]') {
                        seriesPrimaryDataArray.forEach(function (item) {
                            graphRef.series[i].data.push(item)
                        })
                    }
                    return
                }
            }
            var newSeriesPrimary = {
                name: seriesName,
                type: graphRef.yAxis[0].type,
                color: graphFunctions.standard.series.getGraphSeriesColor(idx),
                tooltip: {valueSuffix: '%'},
                data: []
            }
            if (Object.prototype.toString.call(seriesPrimaryDataArray) === '[object Array]') {
                seriesPrimaryDataArray.forEach(function (item) {
                    newSeriesPrimary.data.push(item)
                })
            }
            graphRef.series.push(newSeriesPrimary)
        },
        pushSecondaryDataToGraph: function (graph, seriesName, seriesSecondaryDataArray) {
            var graphRef = dataGraph[graph].data
            var len = graphRef.series.length
            var idx = Math.floor(len / 2)
            for (var i = 0; i < len; i++) {
                if (seriesName === graphRef.series[i].name && graphRef.yAxis[1].type === graphRef.series[i].type) {
                    if (Object.prototype.toString.call(seriesSecondaryDataArray) === '[object Array]') {
                        seriesSecondaryDataArray.forEach(function (item) {
                            graphRef.series[i].data.push(item)
                        })
                    }
                    return
                }
            }
            var newSeriesSecondary = {
                name: seriesName,
                type: graphRef.yAxis[1].type,
                yAxis: 1,
                color: graphFunctions.standard.series.getGraphSeriesColor(idx),
                tooltip: {valueSuffix: ''},
                data: []
            }
            if (Object.prototype.toString.call(seriesSecondaryDataArray) === '[object Array]') {
                seriesSecondaryDataArray.forEach(function (item) {
                    newSeriesSecondary.data.push(item)
                })
            }
            graphRef.series.push(newSeriesSecondary)
        },
        resetAllDataInGraph: function (graph) {
            graphFunctions.standard.resetAllDataInGraph(graph)
        },
        removeSeriesPrimaryAndSecondaryInGraph: function (graph, seriesName) {
            dataGraph[graph].data.series.forEach(function (s, i) {
                if (s.name == seriesName) {
                    dataGraph[graph].data.series.splice(i, 1)   // 删除 primary data
                    dataGraph[graph].data.series.splice(i, 1)   // 删除 secondary data
                    return
                }
            })
        },
    }
}

var yesterday = getYesterdaysDate()


'use strict';
angular.module('backofficeApp.dailyReportingManager.controller', []).filter('object2Array', function () {
    return function (input) {
        var out = [];
        for (i in input) {
            out.push(input[i]);
        }
        return out;
    }
}).controller('dailyReportingCtrl', ['$scope', '$http', '$compile', function ($scope, $http, $compile) {

    /** CACHE: This is the heart of the web page
     *
     *  数据结构: { comm1:{date1:{users:10,vusers:5,questions:30,newusers:...},date2:{users:20,...},...}, comm2:{date1:{users:30,...},...}, comm3:{...}, ...}
     *  e.g. $scope.reportingData[comm1][date2][users] = 20
     */
    $scope.reportingData = {}

    var allCommName = '全部'

    $scope.currentTab = ''  // main, stats, retention, dau

    /**  ========= DEFAULT TIME RANGE =========  */
    $scope.dailyColumn = generateDaysList(onlineDate, new Date())
    $scope.weeklyColumn = generateWeeksList(startAndEndOfWeek(onlineDate)[0], new Date())
    $scope.monthlyColumn = generateMonthsList(startAndEndOfMonth(onlineDate)[0], new Date())


    /**  ========= DISTRICT 大区 =========  */
    $scope.districtList = []

    function getDistrictName(commId) {
        var districtName = ''
        if (commId == 'all') {
            return allCommName
        } else {
            var len = $scope.communityList.length
            for (var i = 0; i < len; i++) {
                if ($scope.communityList[i].objId == commId) {
                    if ($scope.communityList[i].groups && $scope.communityList[i].groups.length > 0) {
                        var grpslen = $scope.communityList[i].groups.length;
                        for (var g = 0; g < grpslen; g++) {
                            for (var j = 0; j < $scope.districtList.length; j++) {
                                if ($scope.districtList[j].objId == $scope.communityList[i].groups[g]) {
                                    districtName += $scope.districtList[j].groupName + ","
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        return districtName.substr(0, districtName.length - 1)
    }

    /**  ========= COMMUNITY 小区 LIST =========  */
    $scope.communityList = []

    function getCommunityName(commId) {
        if (commId == 'all')
            return allCommName
        var commName = ''
        var len = $scope.communityList.length;
        for (var i = 0; i < len; i++) {
            if ($scope.communityList[i].objId == commId) {
                commName = $scope.communityList[i].communityName
                break
            }
        }
        return commName
    }

    function getCommunityEffectiveDate(commId) {
        if (commId == 'all')
            return onlineDate
        var effectiveDate = onlineDate
        var len = $scope.communityList.length;
        for (var i = 0; i < len; i++) {
            if ($scope.communityList[i].objId == commId) {
                effectiveDate = $scope.communityList[i].dateEffective
                break
            }
        }
        return effectiveDate
    }

    /**  ========= COMM DATA API =========  */
    var datatypes = ['users', 'newusers', 'vusers', 'question', 'questionusers', 'replies', 'repliesusers', 'activeusersdaily', 'activeusersweekly', 'activeusersmonthly',
        'realusers', 'realnewusers', 'realvusers', 'realquestion', 'realquestionusers', 'realreplies', 'realrepliesusers', 'realactiveusersdaily', 'realactiveusersweekly', 'realactiveusersmonthly']

    function getCommStatsDataAPI(community, date) {
        var promise = $http.get('http://' + backOfficeHost + '/rest/v1.0/BI/reports/getCommunityMainStatsReport/' + community + '/' + date, {
            headers: {'Content-Type': 'application/json;charset=utf-8'}
        }).then(function (data) {
            var len = data.data.data.length
            if (len == 0) {
                if (!$scope.reportingData[community])
                    $scope.reportingData[community] = {}
                if (!$scope.reportingData[community][date])
                    $scope.reportingData[community][date] = {}
                datatypes.forEach(function (dt) {
                    $scope.reportingData[community][date][dt] = 0
                })
            } else {
                for (var i = 0; i < len; i++) {
                    var commData = data.data.data[i]
                    var comm = commData['commId']
                    var day = commData['date']
                    if (!$scope.reportingData[comm]) {
                        $scope.reportingData[comm] = {}
                        $scope.reportingData[comm]['dateEffective'] = commData['dateEffective']
                    }
                    if (!$scope.reportingData[comm][day])
                        $scope.reportingData[comm][day] = {}
                    datatypes.forEach(function (dt) {
                        $scope.reportingData[comm][day][dt] = !commData[dt] ? 0 : commData[dt]
                    })
                }
            }
            return 'success'
        })
        return promise
    }


    /** ==================================== MAIN PAGE ====================================  */

    var graphColumns = {
        users: '总用户数',
        vusers: '总V用户数',
        question: '发布数',
        questionusers: '发布人数',
        replies: '回复数',
        repliesusers: '回复人数'
    }
    $scope.commsInGraph = {}

    $scope.mainRealUsersSwitch = true;

    /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170825  start   */
    /* 生成小区大使信息Excel */
    $scope.exportModeratorManagerInfoData = function() {

        var startDateSelect = $("#startDateSelect").val();
        if(startDateSelect == '') {
            alert('开始日期不能为空！');
            return;
        }
        var endDateSelect = $("#endDateSelect").val();
        if(endDateSelect == '') {
            alert('结束日期不能为空！');
            return;
        }
        if(startDateSelect > endDateSelect) {
            alert('开始日期不能大于结束日期！');
            return;
        }

        var params = {'startDateSelect': startDateSelect, 'endDateSelect': endDateSelect};
        $http.post('http://' + backOfficeHost + '/rest/v1.0/communities/exportModeratorManagerInfoData', params).then(
            function successCallback(response) {
                var data = response.data.data;
                if(data == null) {
                    alert('导出失败!');
                } else {
                    alert('导出成功件数为:' + data);
                }
            }, function errorCallback(response) {
                alert('导出失败!');
            })
    };
    /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170825  end   */

    $scope.getMainGraphs = function (community, startDate, endDate) {

        community = !community ? 'all' : community
        startDate = !startDate || startDate < onlineDate ? onlineDate : startDate
        endDate = !endDate ? yesterday : endDate      // yesterday's data = latest data

        $scope.commsInGraph[community] = getCommunityName(community)

        $("#loadingMainText").html("Loading Graph...")
        if (!checkAllMainGraphsDataExists(community)) {
            var promise = getCommStatsDataAPI(community, 'all')
            promise.then(function (data) {
                fillCommunityReportingData(community)
                loadMainGraphs(community, startDate, endDate)
            })
        } else {
            loadMainGraphs(community, startDate, endDate)
        }
    }

    function checkAllMainGraphsDataExists(community) {
        if (!$scope.reportingData[community])
            return false
        var len = $scope.weeklyColumn.length;
        for (var i = 0; i < len; i++) {
            var week = $scope.weeklyColumn[i]
            if (!$scope.reportingData[community][week])
                return false
            for (var dt in graphColumns) {
                if ($scope.reportingData[community][week][dt] == null)
                    return false
            }
        }
        return true
    }

    function fillCommunityReportingData(community) {
        for (var dt in datatypes) {
            if (dt.indexOf('active') == -1) {
                var totalCount = 0
                $scope.weeklyColumn.forEach(function (week) {
                    if (!$scope.reportingData[community][week]) {
                        $scope.reportingData[community][week] = {}
                        $scope.reportingData[community][week][dt] = totalCount
                    } else if ($scope.reportingData[community][week][dt] == null) {
                        $scope.reportingData[community][week][dt] = totalCount
                    } else {
                        totalCount = $scope.reportingData[community][week][dt]
                    }
                })
            }
        }
    }

    $scope.toggleMainRealUsers = function (startDate, endDate) {
        for (var comm in $scope.commsInGraph) {
            $scope.getMainGraphs(comm, startDate, endDate)
        }
    }

    function loadMainGraphs(community, startDate, endDate) {
        for (var graphName in graphColumns) {
            graphFunctions.standard.xAxis.clearXAxisCategoryInGraph(graphName)   // reset xAxis
            graphFunctions.standard.series.removeSeriesInGraph(graphName, $scope.commsInGraph[community])
            var idx = 0
            var dt = $scope.mainRealUsersSwitch ? 'real' + graphName : graphName
            $scope.weeklyColumn.forEach(function (week, i) {
                var weekEnding = newIncrementDate(week, 6).format('yyyy-MM-dd')
                if (week < startDate || week > endDate)
                    return
                if (weekEnding > yesterday)
                    weekEnding = yesterday
                graphFunctions.standard.xAxis.pushXAxisCategoryToGraph(graphName, week)
                graphFunctions.standard.series.pushDataToGraph(graphName, $scope.commsInGraph[community], [[idx++, $scope.reportingData[community][weekEnding][dt]]])
            })
            graphFunctions.displayGraph(graphName)
        }
        $("#loadingMainText").html("")
    }

    $scope.refreshMainGraphs = function () {
        for (var g in graphColumns)
            graphFunctions.displayGraph(g)
    }

    $scope.removeCommInGraphs = function (community) {
        for (var g in graphColumns)
            graphFunctions.standard.series.removeSeriesInGraph(g, $scope.commsInGraph[community])
        delete $scope.commsInGraph[community]
        $scope.refreshMainGraphs()
    }


    /** MAIN PAGE INIT */
    var mainPageClicks = 0;
    $scope.initMainPage = function () {
        if (mainPageClicks == 0) {
            initMainGraphs()
            $scope.getMainGraphs('all')
        }
        //$scope.refreshMainGraphs()
        $scope.currentTab = 'main'
        mainPageClicks++
        $(window).resize();

        function initMainGraphs() {
            for (var g in graphColumns) {
                graphFunctions.standard.createGraphObject(g, 'column', graphColumns[g], 'End of Week')
                $('#mainCharts').append('<div id="' + g + 'Chart" style="height: 400px; width: 70%; display: block; margin: auto;"></div>')
            }
        }
    }


    /** =========================================  STATS PAGE  ========================================= */

    $scope.date = new Date().format("yyyy-MM-dd")
    var interval = 1
    var intervaltext = interval == 7 ? 'weekly' : 'daily'

    $scope.commsInStats = {}

    $scope.statsRealUsersSwitch = true;

    var statColumns = ['users', 'newusers', 'vusers', 'newvusers', 'question', 'newquestion', 'questionusers', 'newquestionusers', 'replies', 'newreplies', 'repliesusers', 'newrepliesusers', 'activeusers', 'dau']

    function getDateAndPrevPeriod(date, interval) {
        var d = !date ? yesterday : date   // Today's data does not exist in `66xiaoqu_rec.stats`. Grab 昨天的数据
        var prevPeriod = null
        if (interval == 1) {       // daily 日
            prevPeriod = newIncrementDate(d, -interval).format('yyyy-MM-dd')
            if (prevPeriod < onlineDate)
                prevPeriod = onlineDate
        }
        else if (interval == 7) {     // weekly 周
            var endWeek = startAndEndOfWeek(d)[1]
            var earliestWeek = startAndEndOfWeek(onlineDate)[0]

            d = endWeek
            prevPeriod = newIncrementDate(d, -7).format('yyyy-MM-dd')
            if (prevPeriod < earliestWeek) {
                prevPeriod = earliestWeek
                d = startAndEndOfWeek(earliestWeek)[1]
            }
            else if (d > yesterday) {
                d = yesterday
                prevPeriod = newIncrementDate(d, -7).format('yyyy-MM-dd')
            }
            //prevPeriod = newIncrementDate(new Date(startAndEndOfWeek(d)[0]), -1).format('yyyy-MM-dd')    // compare with previous day of start of the week data (since data is end of day basis)
        }
        return [d, prevPeriod]
    }

    $scope.getAllCommStats = function (date) {
        var date = getDateAndPrevPeriod(date, interval)[0]
        var prevPeriod = getDateAndPrevPeriod(date, interval)[1]

        var promise = getCommStatsDataAPI('every', date)
        promise.then(function (data) {
            var promise2 = getCommStatsDataAPI('every', prevPeriod)
            promise2.then(function (data) {
                var len = $scope.communityList.length;
                for (var i = 0; i < len; i++) {
                    $scope.getCommStats($scope.communityList[i].objId, date)
                }
            })
        })
    }

    $scope.getCommStats = function (community, date) {

        var community = !community ? 'all' : community

        var date = getDateAndPrevPeriod(date, interval)[0]
        var prevPeriod = getDateAndPrevPeriod(date, interval)[1]

        $scope.date = date

        if (community in $scope.commsInStats && $scope.commsInStats[community]['interval'] == intervaltext && $scope.commsInStats[community]['date'] == date) {
            return
        }

        if (checkIfCommStatsDataExists(community, date) && checkIfCommStatsDataExists(community, prevPeriod)) {
            fillCommStatsData(community, date, prevPeriod)
        } else if (checkIfCommStatsDataExists(community, date)) {
            var promise = getCommStatsDataAPI(community, prevPeriod)
            promise.then(function (data) {
                fillCommStatsData(community, date, prevPeriod)
            })
        } else {
            var promise = getCommStatsDataAPI(community, date)
            promise.then(function (data) {
                if (checkIfCommStatsDataExists(community, prevPeriod)) {
                    fillCommStatsData(community, date, prevPeriod)
                } else {
                    var promise2 = getCommStatsDataAPI(community, prevPeriod)
                    promise2.then(function (data) {
                        fillCommStatsData(community, date, prevPeriod)
                    })
                }
            })
        }
    }

    $scope.getCommsStatsInDistrict = function (district, date) {
        var len = $scope.communityList.length
        for (var i = 0; i < len; i++) {
            var grps = $scope.communityList[i].groups
            if (grps && grps.length != 0) {
                var grpslen = grps.length
                for (var g = 0; g < grpslen; g++) {
                    if (grps[g] == district) {
                        var community = $scope.communityList[i].objId
                        if (!(community in $scope.commsInStats))
                            $scope.getCommStats(community, date)
                    }
                }
            }
        }
    }

    function checkIfCommStatsDataExists(community, date) {
        if (!$scope.reportingData[community])
            return false
        else if (!$scope.reportingData[community][date])
            return false
        else
            return true
    }

    function fillCommStatsData(community, date, prevPeriod) {
        $scope.commsInStats[community] = {}
        $scope.commsInStats[community]['interval'] = intervaltext
        $scope.commsInStats[community]['commName'] = getCommunityName(community)
        $scope.commsInStats[community]['district'] = getDistrictName(community)
        $scope.commsInStats[community]['dateEffective'] = getCommunityEffectiveDate(community)
        $scope.commsInStats[community]['date'] = interval == 7 ? startAndEndOfWeek(date)[0] : date

        var real = $scope.statsRealUsersSwitch ? 'real' : ''

        var lenStat = statColumns.length

        for (var i = 0; i < lenStat; i++) {
            var datatype = statColumns[i]

            if (datatype.indexOf('new') > -1 && prevPeriod) {
                if($scope.reportingData[community][date][real + datatype] == null || $scope.reportingData[community][date][real + datatype] == 0){
                    var type = datatype.replace("new", "")
                    $scope.commsInStats[community][datatype] = $scope.reportingData[community][date][real + type] - $scope.reportingData[community][prevPeriod][real + type]
                }else{
                    $scope.commsInStats[community][datatype] = $scope.reportingData[community][date][real + datatype]
                }
            }
            else if (datatype.indexOf('activeusers') > -1) {
                $scope.commsInStats[community][datatype] = $scope.reportingData[community][date][real + 'activeusers' + intervaltext]
            }
            else if (datatype.indexOf('dau') > -1) {
                var dau = (($scope.reportingData[community][date][real + 'activeusers' + intervaltext] / $scope.reportingData[community][date][real + 'users']) * 100).toFixed(2)
                $scope.commsInStats[community][datatype] = isNaN(dau) ? "0.00%" : dau + "%"
            }
            else {
                $scope.commsInStats[community][datatype] = $scope.reportingData[community][date][real + datatype]
            }
        }
    }

    $scope.getCommStatsByDate = function (date) {
        if (Object.keys($scope.commsInStats).length >= 10) {
            var date = getDateAndPrevPeriod(date, interval)[0]
            var prevPeriod = getDateAndPrevPeriod(date, interval)[1]

            var allExists = true
            /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170825  start   */
            // js报红
            // for (c in $scope.commsInStats) { // 旧
            for (var c in $scope.commsInStats) { // 新
                /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170825  end   */
                if (!(checkIfCommStatsDataExists(c, date)) || !(checkIfCommStatsDataExists(c, prevPeriod))) {
                    allExists = false
                    break
                }
            }
            if (allExists) {
                for (var community in $scope.commsInStats) {
                    fillCommStatsData(community, date, prevPeriod)
                }
            } else {
                var promise = getCommStatsDataAPI('every', date)
                promise.then(function (data) {
                    var promise2 = getCommStatsDataAPI('every', prevPeriod)
                    promise2.then(function (data) {
                        for (var community in $scope.commsInStats) {
                            $scope.getCommStats(community, date)
                        }
                    })
                })
            }
        } else {
            /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170825  start   */
            // js报红
            // for (c in $scope.commsInStats) { // 旧
            for (var c in $scope.commsInStats) { // 新
                /*  宝宝树66小区二次改造    mod   guo.xiaomin  20170825  end   */
                $scope.getCommStats(c, date)
            }
        }
    }

    $scope.setDateInterval = function (date, setinterval) {
        interval = setinterval
        intervaltext = setinterval == 7 ? 'weekly' : 'daily'
        $scope.getCommStatsByDate(date)
    }

    $scope.toggleStatsRealUsers = function (date) {
        var date = getDateAndPrevPeriod(date, interval)[0]
        var prevPeriod = getDateAndPrevPeriod(date, interval)[1]
        for (var community in $scope.commsInStats) {
            if ($scope.commsInStats[community]['date'] == date) {
                fillCommStatsData(community, date, prevPeriod)
            } else {
                $scope.getCommStats(community, date)
            }
        }
    }

    $scope.clearCommStats = function () {
        $scope.commsInStats = {}
    }

    $scope.removeCommInStats = function (commId) {
        delete $scope.commsInStats[commId]
    }

    $scope.orderByField = 'dateEffective';
    $scope.reverseSort = true;

    $scope.exportStatsData = function () {
        var blob = new Blob([document.getElementById('exportable').innerHTML], {
            type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
        });
        saveAs(blob, "StatsData.xls");
    }


    /** STATS PAGE INIT */
    var statsPageClicks = 0;
    $scope.initStatsPage = function () {
        if (statsPageClicks == 0) {
            $scope.getCommStats('all')
        }
        $scope.currentTab = 'stats'
        statsPageClicks++;
    }


    /** ====================================== RETENTION PAGE ======================================  */

    $scope.commsInRetention = {}

    var retentionIntervals = ['daily', 'weekly', 'monthly']
    $scope.retentionIntervals = retentionIntervals

    $scope.retentionData = {daily: {}, weekly: {}, monthly: {}}
    // $scope.retentionData.weekly = {comm1: {userBatchDate1: {totalUsers: 500, data : {week1:{active: 250, retentionRate: 50%}, week2:{active: 100, retentionRate: 20%}, ...}}, userBatchDate2: {totalUsers: 100, data: {week1:{}}, ...}, ...}, comm2: {...}, ...}
    // $scope.retentionData.weekly['comm1'][userBatchDate1]['totalUsers'] = 500
    // $scope.retentionData.weekly['comm1'][userBatchDate1].data['week2']['active'] = 100

    $scope.getRetentionGraphs = function (community) {

        if (!community)
            community = 'all'

        if ($scope.commsInRetention[community])
            return
        $scope.commsInRetention[community] = getCommunityName(community)

        retentionIntervals.forEach(function (rInterval) {
            if (!$scope.retentionData[rInterval][community]) {
                var promise = getIntervalRetentionByCommAPI(rInterval, community, 'all', 'all')
                promise.then(function (data) {
                    displayRetentionGraph(rInterval, community)
                })
            } else {
                displayRetentionGraph(rInterval, community)
            }
        })
    }

    function displayRetentionGraph(rInterval, community) {
        var graphName = rInterval + 'Retention'
        var idx = 0
        $scope[rInterval + 'Column'].forEach(function (date) {
            graphFunctions.combo.xAxis.pushXAxisCategoryToGraph(graphName, date)
            var totalUsers = $scope.weightedAveRetention[rInterval][community][date].total
            var weightedAveRet = $scope.weightedAveRetention[rInterval][community][date].weightedAveRet
            //if(totalUsers == 0)
            //    return

            //var idx = 0
            //if (rInterval == 'daily')
            //    idx = getDayDiff(onlineDate, date)
            //else if (rInterval == 'weekly')
            //    idx = getWeekDiff(onlineDate, date)
            //else if (rInterval == 'monthly')
            //    idx = getMonthDiff(onlineDate, date)
            if (totalUsers > 0) {
                graphFunctions.combo.series.pushSecondaryDataToGraph(graphName, $scope.commsInRetention[community], [[idx, totalUsers]])
                if (idx > 0)
                    graphFunctions.combo.series.pushPrimaryDataToGraph(graphName, $scope.commsInRetention[community], [[idx, Math.round((weightedAveRet * 100) * 100) / 100]])
            }
            idx += 1
        })
        graphFunctions.displayGraph(graphName)
    }

    $scope.refreshRetentionGraphs = function () {
        retentionIntervals.forEach(function (rInterval) {
            graphFunctions.displayGraph(rInterval + 'Retention')
        })
    }

    $scope.removeCommInRetention = function (community) {
        retentionIntervals.forEach(function (rInterval) {
            var graph = rInterval + 'Retention'
            graphFunctions.combo.series.removeSeriesPrimaryAndSecondaryInGraph(graph, $scope.commsInRetention[community])
        })
        delete $scope.commsInRetention[community]
        $scope.refreshRetentionGraphs()
    }

    function loadIntervalRetData(rInterval, community, data) {
        $scope.retentionData[rInterval][community] = {}
        data.data.data.forEach(function (item) {
            var batchDate = item.batchDate
            if (!$scope.retentionData[rInterval][community][batchDate]) {
                $scope.retentionData[rInterval][community][batchDate] = {
                    total: item.total
                }
            }
            if (item.period == 1) {
                $scope.retentionData[rInterval][community][batchDate].retention = item.periodRet
            }
        })
        fillRetentionData(rInterval, community)
    }

    function fillRetentionData(rInterval, community) {
        $scope[rInterval + 'Column'].forEach(function (date) {
            var data = $scope.retentionData[rInterval][community]
            if (!data[date]) {
                data[date] = {total: 0, retention: 0}
            } else {
                if (!data[date].retention) {
                    data[date].retention = 0
                }
            }
        })
    }

    $scope.weightedAveRetention = {daily: {}, weekly: {}, monthly: {}}

    function loadWeightedAveRetention(rInterval, community) {
        $scope.weightedAveRetention[rInterval][community] = {}
        var weightedAveRet = 0
        var cumulativeTotal = 0
        $scope[rInterval + 'Column'].forEach(function (date) {
            var batchTotal = $scope.retentionData[rInterval][community][date].total
            cumulativeTotal += batchTotal
            $scope.weightedAveRetention[rInterval][community][date] = {
                total: cumulativeTotal,
                weightedAveRet: weightedAveRet
            }  // weightedAveRet for that period = weightedAveRet up to the previous period
            weightedAveRet = (cumulativeTotal - batchTotal) / cumulativeTotal * weightedAveRet + batchTotal / cumulativeTotal * $scope.retentionData[rInterval][community][date].retention
            if (isNaN(weightedAveRet))
                weightedAveRet = 0
        })
    }


    function getIntervalRetentionByCommAPI(rInterval, community, startDate, endDate) {
        var promise = $http.get('http://' + backOfficeHost + '/rest/v1.0/BI/reports/getIntervalRetentionByComm/' + rInterval + '/' + community + '/' + startDate + '/' + endDate, {
            headers: {'Content-Type': 'application/json;charset=utf-8'}
        }).then(function (data) {
            loadIntervalRetData(rInterval, community, data)
            loadWeightedAveRetention(rInterval, community)
            loadBatchRetTable(rInterval, community, data)
            return 'success'
        });
        return promise
    }


    /** RETENTION TABLE */


    $scope.retTableDisplay = {}

    $scope.batchRetTable = {daily: {}, weekly: {}, monthly: {}}
    $scope.periodText = '天'     // 天, 周, 月
    $scope.currentBatchRetInterval = 'daily'    // daily, weekly, monthly
    $scope.retTableComm = ''
    $scope.retTableCommName = ''
    //$scope.retTableStartDate = onlineDate
    //$scope.retTableEndDate = new Date().format('yyyy-MM-dd')

    var periodText = {daily: '天', weekly: '周', monthly: '月'}

    $scope.getCommRetentionTable = function (rInterval, community, startDate, endDate) {

        rInterval = !rInterval ? 'daily' : rInterval
        community = !community ? 'all' : community
        startDate = !startDate ? getCommunityEffectiveDate(community) : startDate
        endDate = !endDate ? new Date().format('yyyy-MM-dd') : endDate

        $scope.retTableComm = community
        $scope.retTableCommName = getCommunityName(community)
        $scope.currentBatchRetInterval = rInterval
        $scope.periodText = periodText[rInterval]

        $("#loadingRetTableText").html("Loading...")

        if (!$scope.batchRetTable[rInterval][community]) {
            var promise = getIntervalRetentionByCommAPI(rInterval, community, 'all', 'all')
            promise.then(function (data) {
                displayRetTable(rInterval, community, startDate, endDate)
            })
        } else {
            displayRetTable(rInterval, community, startDate, endDate)
        }
    }

    function displayRetTable(rInterval, community, startDate, endDate) {
        $scope.retTableDisplay = {}
        var cache = $scope.batchRetTable[rInterval][community]
        for (var date in cache) {
            if (date > startDate && date < endDate) {
                $scope.retTableDisplay[date] = {}
                for (var data in cache[date]) {
                    $scope.retTableDisplay[date][data] = cache[date][data]
                }
            }
        }
        calculateRetTableAverage()
        $("#loadingRetTableText").html("")
    }

    function loadBatchRetTable(rInterval, community, data) {
        $scope.batchRetTable[rInterval][community] = {}
        var cache = $scope.batchRetTable[rInterval][community]
        data.data.data.forEach(function (item) {
            var batchDate = item.batchDate
            var batchUsers = item.total
            if (!cache[batchDate]) {
                cache[batchDate] = {}
                cache[batchDate]['total'] = batchUsers
            }
            var period = 'period' + item.period
            cache[batchDate][period] = item.periodRet
        })
    }

    function calculateRetTableAverage() {
        var display = $scope.retTableDisplay
        display['average'] = {
            total: 0,
            period0: 0,
            period1: 0,
            period2: 0,
            period3: 0,
            period4: 0,
            period5: 0,
            period6: 0,
            period7: 0
        }
        var totalUsers = 0
        for (var date in display) {
            if (date == 'average')
                continue
            var batchUsers = display[date].total
            totalUsers += batchUsers
            display['average'].total += batchUsers
            for (var data in display[date]) {
                if (data.indexOf('period') > -1) {
                    display['average'][data] = (totalUsers - batchUsers) / totalUsers * display['average'][data] + (batchUsers) / totalUsers * display[date][data]
                }
            }
        }
        // Convert data to %
        for (var date in display) {
            for (var data in display[date]) {
                if (data == 'total')
                    continue
                display[date][data] = (Math.round((display[date][data] * 100) * 100) / 100) + "%"
            }
        }
    }

    $scope.exportDailyRetTableData = function () {
        var blob = new Blob([document.getElementById('exportRetTable').innerHTML], {
            type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
        });
        saveAs(blob, "{0} {1}Retention.xls".format($scope.retTableCommName, $scope.currentBatchRetInterval));
    }


    /** RETENTION PAGE INIT */
    var retentionPageClicks = 0;
    $scope.initRetentionPage = function () {
        if (retentionPageClicks == 0) {
            initRetentionGraphs()
            $scope.getRetentionGraphs('all')
            $scope.getCommRetentionTable('daily', 'all')
            $("#retentionStart").html(onlineDate)
            $("#retentionEnd").html(new Date().format('yyyy-MM-dd'))
        }
        else {
            //$scope.refreshRetentionGraphs()
        }
        $scope.currentTab = 'retention'
        retentionPageClicks++;
        $(window).resize();
    }

    function initRetentionGraphs() {
        retentionIntervals.forEach(function (rInterval) {
            var graphName = rInterval + 'Retention'
            var title = graphName.capitalize() + " (%) (Weighted Average) vs Users"
            graphFunctions.combo.createGraphObject(graphName, 'spline', 'column', title)

            // Config primary yAxis title and labels
            graphFunctions.combo.yAxis.primary.setTitle(graphName, graphName.capitalize() + " (%)")
            graphFunctions.combo.yAxis.primary.setFormat(graphName, "{value}%")

            // Config secondary yAxis title and labels
            graphFunctions.combo.yAxis.secondary.setTitle(graphName, 'Users')
            graphFunctions.combo.yAxis.secondary.setFormat(graphName, "{value}")

            $('#retentionCharts').append('<div id="' + graphName + 'Chart" style="height: 400px; width: 70%; display: block; margin: auto;"></div>')
        })
    }

    /** =============================== DAU PAGE ========================================  */

    var dauIntervals = ['daily', 'weekly', 'monthly']
    $scope.commsInDau = {}
    $scope.dauRealUsersSwitch = true;

    $scope.getDauGraphs = function (community) {
        $('#loadingDauText').html('Loading...')
        community = !community ? 'all' : community
        $scope.commsInDau[community] = getCommunityName(community)
        if (!$scope.reportingData[community]) {
            var promise = getCommStatsDataAPI(community, 'all')
            promise.then(function (data) {
                loadDauGraphs(community)
                loadDauTables(community)
                $('#loadingDauText').html('')
            })
        } else {
            loadDauGraphs(community)
            loadDauTables(community)
            $('#loadingDauText').html('')
        }
    }

    $scope.dauTableDisplay = []
    $scope.wauTableDisplay = []
    $scope.mauTableDisplay = []

    function loadDauTables(community) {
        var real = $scope.dauRealUsersSwitch ? 'real' : ''
        var commName = $scope.commsInDau[community]
        dauIntervals.forEach(function (dInterval) {
            var period = periodText[dInterval]
            var display = $scope[dInterval[0] + 'auTableDisplay']
            var timeRange = $scope[dInterval + 'Column']
            timeRange.forEach(function (date) {
                if (!$scope.reportingData[community][date])
                    return

                var endDate = null
                if (dInterval == 'daily') {
                    endDate = date
                } else if (dInterval == 'weekly') {
                    endDate = startAndEndOfWeek(date)[1]
                } else if (dInterval == 'monthly') {
                    endDate = startAndEndOfMonth(date)[1]
                }
                if (endDate > yesterday)
                    endDate = yesterday     // latest data

                var active = $scope.reportingData[community][endDate][real + 'activeusers' + dInterval]
                var users = $scope.reportingData[community][endDate][real + 'users']
                var dau = active > users ? 1 : active / users
                //var dau = active / users
                //dau = isNaN(dau) ? 0 : Math.round((dau * 100) * 100) / 100

                var data = {
                    period: period,
                    comm: commName,
                    date: date,
                    active: active,
                    users: users,
                    activerate: dau
                }
                display.push(data)
            })
        })
    }

    $scope.orderByFieldDau = 'date';
    $scope.reverseSortDau = false;

    function loadDauGraphs(community) {
        var real = $scope.dauRealUsersSwitch ? 'real' : ''
        var onlineDateWeek = startAndEndOfWeek(onlineDate)[0]
        var onlineDateMonth = startAndEndOfMonth(onlineDate)[0]
        dauIntervals.forEach(function (dInterval) {
            var graphName = dInterval + 'Dau'
            var timeRange = $scope[dInterval + 'Column']
            timeRange.forEach(function (date) {
                if (!$scope.reportingData[community][date])
                    return

                var dateIdx = null
                var endDate = null
                if (dInterval == 'daily') {
                    endDate = date
                    dateIdx = getDayDiff(onlineDate, endDate)
                } else if (dInterval == 'weekly') {
                    endDate = startAndEndOfWeek(date)[1]
                    dateIdx = getWeekDiff(onlineDateWeek, endDate)
                } else if (dInterval == 'monthly') {
                    endDate = startAndEndOfMonth(date)[1]
                    dateIdx = getMonthDiff(onlineDateMonth, endDate)
                }

                if (endDate > yesterday)
                    endDate = yesterday     // latest data

                var active = $scope.reportingData[community][endDate][real + 'activeusers' + dInterval]
                var users = $scope.reportingData[community][endDate][real + 'users']
                var dau = active > users ? 1 : active / users
                //var dau = active / users
                dau = isNaN(dau) ? 0 : Math.round((dau * 100) * 100) / 100

                graphFunctions.combo.series.pushSecondaryDataToGraph(graphName, $scope.commsInDau[community], [[dateIdx, users]])
                graphFunctions.combo.series.pushPrimaryDataToGraph(graphName, $scope.commsInDau[community], [[dateIdx, dau]])
            })
            graphFunctions.displayGraph(dInterval + 'Dau')
        })
    }

    $scope.getCommsDauInDistrict = function (district) {
        var len = $scope.communityList.length
        for (var i = 0; i < len; i++) {
            var grps = $scope.communityList[i].groups
            if (grps && grps.length != 0) {
                var grpslen = grps.length
                for (var g = 0; g < grpslen; g++) {
                    if (grps[g] == district) {
                        var community = $scope.communityList[i].objId
                        if (!(community in $scope.commsInDau)) {
                            $scope.getDauGraphs(community)
                        }
                    }
                }
            }
        }
    }

    $scope.toggleDauRealUsers = function () {
        dauIntervals.forEach(function (dInterval) {
            $scope[dInterval[0] + 'auTableDisplay'] = []
        })
        for (var c in $scope.commsInDau) {
            dauIntervals.forEach(function (dInterval) {
                graphFunctions.combo.series.removeSeriesPrimaryAndSecondaryInGraph(dInterval + 'Dau', $scope.commsInDau[c])
            })
            $scope.getDauGraphs(c)
        }
    }

    $scope.refreshDauGraphs = function () {
        dauIntervals.forEach(function (dInterval) {
            graphFunctions.displayGraph(dInterval + 'Dau')
        })
    }

    $scope.removeCommInDau = function (community) {
        var commName = $scope.commsInDau[community]
        dauIntervals.forEach(function (dInterval) {
            graphFunctions.combo.series.removeSeriesPrimaryAndSecondaryInGraph(dInterval + 'Dau', $scope.commsInDau[community])
            var display = $scope[dInterval[0] + 'auTableDisplay']
            var len = display.length
            for (var i = len - 1; i >= 0; i--) {
                if (display[i].comm == commName)
                    display.splice(i, 1)
            }
        })
        delete $scope.commsInDau[community]
        $scope.refreshDauGraphs()
    }

    $scope.exportDauData = function () {
        var tableList = []
        dauIntervals.forEach(function (dInterval) {
            var dName = dInterval[0] + 'au'
            var tableId = 'export' + dName.capitalize() + 'Table'
            tableList.push(document.getElementById(tableId).innerHTML)
        })
        var blob = new Blob(tableList, {
            type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
        });
        saveAs(blob, "{0} DauWauMau.xls".format($scope.dauRealUsersSwitch ? 'Real Users' : 'All Users'));
    }


    /** DAU PAGE INIT */
    var dauPageClicks = 0;
    $scope.initDauPage = function () {
        //$scope.refreshDauGraphs()
        $(window).resize();
        if (dauPageClicks == 0) {
            initDauGraphs()
            $scope.getDauGraphs('all')
            $("#dauStart").html(onlineDate)
            $("#dauEnd").html(new Date().format('yyyy-MM-dd'))
        }
        else {
        }
        $scope.currentTab = 'dau'
        dauPageClicks++;
    }

    function initDauGraphs() {
        dauIntervals.forEach(function (dInterval) {
            var graphName = dInterval + 'Dau'
            var title = dInterval.capitalize() + ' Active Users (%)'
            graphFunctions.combo.createGraphObject(graphName, 'spline', 'column', title)

            // Config primary yAxis title and labels
            graphFunctions.combo.yAxis.primary.setTitle(graphName, title)
            graphFunctions.combo.yAxis.primary.setFormat(graphName, "{value}%")

            // Config secondary yAxis title and labels
            graphFunctions.combo.yAxis.secondary.setTitle(graphName, 'Total Users')
            graphFunctions.combo.yAxis.secondary.setFormat(graphName, "{value}")

            $('#dauCharts').append('<div id="' + graphName + 'Chart" style="height: 400px; width: 70%; display: block; margin: auto;"></div>')

            graphFunctions.combo.xAxis.pushTimeCategoryToGraph(graphName, $scope[dInterval + 'Column'])
        })
    }

    /** ============================================================================  */


    function initReportPage() {
        $scope.date = new Date().format("yyyy-MM-dd")

        // Get xiaoqu + daqu list
        getCommunityListAPI()
        getDistrictListAPI()

        // init main page
        $scope.initMainPage()

        function getCommunityListAPI() {
            $http.get('http://' + backOfficeHost + '/rest/v1.0/communities/getAllCommunityFromSQL', {
                headers: {'Content-Type': 'application/json;charset=utf-8'}
            }).success(function (data) {
                var len = data.data.length
                for (var i = 0; i < len; i++) {
                    if (data.data[i].isValid == 'True')
                        $scope.communityList.push(data.data[i])
                }
            }).error(function () {
            });
        }

        function getDistrictListAPI() {
            $http.get('http://' + backOfficeHost + '/rest/v1.0/communities/getAllCommunityGroups', {
                headers: {'Content-Type': 'application/json;charset=utf-8'}
            }).success(function (data) {
                $scope.districtList = data.data
            }).error(function () {
            });
        }
    }

    initReportPage()

    //
    //$scope.printOut = function () {
    //    //console.info($scope.testdata)
    //    //$("#aaa").html($compile($scope.date)($scope))
    //    //console.info($scope.reportingData)
    //    //console.log($scope.commsInStats)
    //    console.log($scope.communityList)
    //}

}])